const path = require('path');
const moment = require('moment'); // require
const getDao = require('./databaseService');
const {unCompressFromBuffer} = require('./fileService');
const { version } = require('moment');

const ACTION = {
    NEW_PROJECT: 'newProject',
    LIST_PROJECT: 'listProjects',
    NEW_VERSION: 'newVersion',
    FIND_PROJECT_BYID: 'findProjectById',
    // Ack 
    NEW_PROJECT_ACK: 'newProjectAck',
    LIST_PROJECT_ACK: 'listProjectsAck',
    NEW_VERSION_ACK: 'newVersionAck',
    // File
    FILE_PREUPLOAD: 'preupload',
    FILE_UPLOAD: 'upload',
    FILE_PREUPLOAD: 'preupload',
    FILE_AFTERUPLOAD: 'afterupload'
}
const buildError = (errMsg,code)=>{
    return {
      success:false,
      code:code?code:100,
      errMsg:errMsg
    }
}
const buildSuccess = (data)=>{
    return {
      success:true,
      code:100,
      data:data,
      errMsg:''
    }
}
class Client {
    constructor(socket) {
        this.socket;
        this.filepool = [];
        this.initEvents(socket,this.filepool);

    }
    initEvents(socket,filepool) {
        socket.on(ACTION.LIST_PROJECT, (filter, cb) => {
            console.log("find all project,filter:", filter, cb);
            // TODO: 增加搜索功能
            let dao = getDao();
            dao.listProjects().then((projects) => {
                cb && cb(buildSuccess(projects));
            }).catch((e) => {
                console.error(e);
                cb && cb(null);
            });
        });

        socket.on(ACTION.NEW_VERSION, (data, cb) => {
            let dao = getDao();
            console.log(data);
            let newVersion = { ...data };

            dao.findProjectById(newVersion.projectId).then((project) => {
                if (!project) {
                    cb && cb(buildError('找不到项目。',-1003));

                } else {
                    newVersion.webPath = project.projectId+'_'+moment().format('YYMMDDHHmm');
                    newVersion.filePath = path.join(process.env.STORAGE_ROOT, newVersion.webPath);
                    console.log("add Version:" ,newVersion);
                    dao.addVersion(newVersion).then((version) => {
                        console.log("new Version:",version);
                        project.currentVersionId = version.versionId;
                        project.save().then((newProject) => {
                            console.log("更新项目结果：", newProject)
                            cb && cb(buildSuccess({ newProject, version }));
                        }).catch((e) => {
                            console.error(e);
                            cb && cb(buildError('更新版本时项目更新失败。',-1004));
                        });

                    }).catch((e) => {
                        console.error(e);
                        cb && cb(buildError('新增版本失败',-1005));
                    })
                }
            }).catch((e) => {
                console.error(e);
                cb && cb(buildError('新增版本时查询项目失败',-1006));
            });
        });
        socket.on(ACTION.FIND_PROJECT_BYID, (projectId, cb) => {
            let dao = getDao();
            console.log(projectId);
            dao.findProjectById(projectId).then((project) => {
                cb && cb(buildSuccess(project));
            }).catch((e) => {
                const error = buildError("查询项目失败！",-1002);
                console.error("find project by id error:",e,cb,error);
                cb && cb(error);
            });
        });
        socket.on(ACTION.NEW_PROJECT, (project, cb) => {
            let dao = getDao();
            console.log(project);
            dao.addProject(project).then((newProject) => {
                cb && cb(buildSuccess(newProject));
            }).catch((e) => {
                const error = buildError("创建项目失败！",-1001);
                console.error("add project error:",e,cb,error);
                cb && cb(error);
            });
        });

        //File upload process
        socket.on(ACTION.FILE_PREUPLOAD, (data, callback) => {
            console.log('pre upload',data);
            const { projectId,versionId,fileId,overwrite } = data;
            let dao = getDao();
            dao.findVersionById(versionId).then((version)=>{
                if(version != null){
                    //找到Version
                    if (Object.hasOwnProperty.call(filepool, fileId)) {
                        if (overwrite) {
                            filepool[fileId] = { data: [],filePath:version.filePath };
                            callback(buildSuccess('重置成功'));
                        } else {
                            callback(buildError('文件已经存在',-1007));
                        }
                    } else {
                        filepool[fileId] = { data: [],filePath:version.filePath };
                        console.log("文件缓存设置成功",filepool[fileId]);
                        callback(buildSuccess('文件缓存设置成功'));
                    }
                }else{
                    callback(buildError('版本不存在！',-1008));
                }
            })
        });
        socket.on(ACTION.FILE_UPLOAD, (data,callback) => {
            try {
                //console.log('upload',data);
                const { projectId,versionId,fileId,buffer } = data;
                if (Object.hasOwnProperty.call(filepool, fileId)) {
                    const file = filepool[fileId];
                    file.data.push(buffer);
                    callback && callback(buildSuccess({totlSize:file.data.length}));
                    //console.log('upload file', fileId, buffer ? buffer.byteLength : 0);
                } else {
                    callback && callback(buildError('未找到文件缓存',-1009));
                    console.log('upload file can not find file:', fileId, 'datasize:', buffer ? buffer.byteLength : 0);
                }
            } catch (e) {
                console.log(e);
            }
        });
        socket.on(ACTION.FILE_AFTERUPLOAD, (data,cb) => {
            try {
                console.log('afterupload', data);
                const { projectId,versionId,fileId ,filePath,projectName} = data;
                if (Object.hasOwnProperty.call(filepool, fileId)) {
                    const file = filepool[fileId];
                    let zipBuffer = Buffer.concat(file.data);
                    console.log("total size:", zipBuffer.length);
                    unCompressFromBuffer(filePath, zipBuffer);
                    cb && cb(buildSuccess('文件上传完成。'));
                }
            } catch (e) {
                console.log(e);
            }
        });
    }
}

module.exports = Client;